package com.xiyuan.smartutils;

import com.xiyuan.smartutils.constants.SignConstants;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

import static com.xiyuan.smartutils.Colors.colorInRange;
import static com.xiyuan.smartutils.Colors.toRgb;

/**
 * 图片工具类
 *
 * @version v1.0.0 @author lgz 2017-6-1 新建与整理
 */

@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
public final class Images implements SignConstants {
    
    private Images() {
    }
    
   
    /**
     * 图片压缩成PNG格式
     *
     * @param data   图片数据
     * @param width  压缩后宽度
     * @param height 压缩后高度
     * @throws IOException IO异常
     */
    public static byte[] resizePng(byte[] data, int width, int height) throws IOException {
        Asserts.nonNull(data);
        
        ByteArrayInputStream input = new ByteArrayInputStream(data);
        BufferedImage src = ImageIO.read(input);
        
        BufferedImage buffImg = null;
        if (src.isAlphaPremultiplied()) {
            // 判断alpha通道是否需要变为透明的
            buffImg = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
        }
        else {
            buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        }
        
        // 压缩时作平滑处理
        Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        
        Graphics2D g = (Graphics2D) buffImg.getGraphics();
        
        // Color.white防止背景有时变黑
        g.drawImage(image, 0, 0, width, height, Color.white, null);
        g.dispose();
        
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        ImageIO.write(buffImg, _PNG_, output);
        
        return output.toByteArray();
    }
    
    
    /***
     * 设置图片透明度
     *
     * @param src       原图片
     * @param bg_alpha  背景透明度0-255；255表示不透明
     * @param alpha     内容透明度0-255；255表示不透明
     * @return BufferedImage
     */
    public static BufferedImage setAlpha(BufferedImage src, int bg_alpha, int alpha) {
        
        if (bg_alpha < 0 || bg_alpha > 255 || alpha < 0 || alpha > 255) {
            throw new IllegalArgumentException("alpha must be between 0-255");
        }
        
        // 高度和宽度
        int height = src.getHeight();
        int width = src.getWidth();
        
        // 生产背景透明和内容透明的图片
        ImageIcon imageIcon = new ImageIcon(src);
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
        // 获取画笔
        Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
        // 绘制Image的图片
        g2D.drawImage(imageIcon.getImage(), 0, 0, null);
        
        // 外层遍历是Y轴的像素
        for (int y = bufferedImage.getMinY(); y < bufferedImage.getHeight(); y++) {
            // 内层遍历是X轴的像素
            for (int x = bufferedImage.getMinX(); x < bufferedImage.getWidth(); x++) {
                int rgb = bufferedImage.getRGB(x, y);
                // 对当前颜色判断是否在指定区间内
                if (colorInRange(rgb)) {
                    rgb = (bg_alpha << 24) | (rgb & 0x00ffffff);
                }
                else {
                    // #AARRGGBB 最前两位为透明度
                    rgb = (alpha << 24) | (rgb & 0x00ffffff);
                }
                
                bufferedImage.setRGB(x, y, rgb);
            }
        }
        // 绘制设置了RGB的新图片
        g2D.drawImage(bufferedImage, 0, 0, null);
        return bufferedImage;
    }
    
    /**
     * 设置背景透明度
     *
     * @param src   原图片
     * @param alpha 背景透明度0-255；255表示不透明
     * @return BufferedImage
     */
    public static BufferedImage setBackgroundAlpha(BufferedImage src, int alpha) {
        return setAlpha(src, alpha, 255);
    }
    
    /**
     * 设置背景透明度
     *
     * @param src   原图片
     * @param alpha 内容透明度0-255；255表示不透明
     * @return BufferedImage
     */
    public static BufferedImage setContentAlpha(BufferedImage src, int alpha) {
        
        return setAlpha(src, 255, alpha);
    }
    
    /****
     * 字体转图片
     *
     * @param font      字体对象
     * @param padding   图片内边距
     * @param fontSize  字体大小，默认12、单位像素
     * @param hexCode   Unicode字符编码
     * @param hexColor  16进制的颜色
     * @param alpha     字体透明度0-255；255表示不透明
     * @return 字体图片 size = fontSize+padding
     * @throws Exception 异常信息
     */
    public static BufferedImage transferFontToImage(Font font, int padding, float fontSize, String hexCode,
                                                    String hexColor,
                                                    int alpha) throws Exception {
        if (padding < 0) {padding = 0;}
        
        if (fontSize <= 0) {fontSize = 12;}
        
        font = font.deriveFont(fontSize);
        int imgSize = (int) (padding * 2 + fontSize);
        BufferedImage image = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_4BYTE_ABGR_PRE);
        Graphics2D g = image.createGraphics();
        // 设置透明
        image = g.getDeviceConfiguration().createCompatibleImage(imgSize, imgSize, Transparency.TRANSLUCENT);
        g = image.createGraphics();
        
        // 设置“抗锯齿”的属性
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        
        // 设置字体颜色
        g.setFont(font);
        Colors.Rgb rgb = toRgb(hexColor);
        g.setColor(new Color(rgb.r, rgb.g, rgb.b, alpha));
        
        // 会话字体
        FontMetrics fm = g.getFontMetrics();
        
        int stringWidth = fm.stringWidth(hexCode);
        
        int stringAscent = fm.getAscent();
        int stringDescent = fm.getDescent();
        
        int x = image.getWidth() / 2 - stringWidth / 2;
        int y = image.getHeight() / 2 + (stringAscent - stringDescent) / 2;
        g.drawString(hexCode, x, y);
        
        return image;
    }
}
